home *** CD-ROM | disk | FTP | other *** search
- Date: Thu, 10 Sep 1998 10:26:06 +0200
- From: Michal Zalewski <lcamtuf@IDS.PL>
- To: BUGTRAQ@netspace.org
- Subject: [Linux] klogd 1.3-22 buffer overflow
-
- Good morning,
-
- This time - buffer overflow in Linux klogd daemon from sysklogd-1.3
- package (up to release 22 - affects Red Hat 5.x and Slackware 3.x, no data
- about other distributions).
-
- The problem:
-
- Kernel messages are stored in 4 kB cyclic printk ring. Klogd reads this
- buffer using /proc/kmsg to 4 kB long buffer, that's good. But then, data
- is split into lines, by copying data until '\n' is reached. What a pity,
- line buffer is only 1 kB long - sometimes, it's not enough... Exploitable?
- Could be...
-
- Impact:
-
- To exploit this security hole, we have to generate very long kernel
- message (or a lot of short messages with no '\n' inside). There are two
- potential ways of doing this:
-
- a) In kernel source (or any of installed modules), find printk not
- terminated with '\n'. There are some old, obscure messages both in
- 2.0.xx and 2.1.xxx. Yep, but what now? You have to generate it :-S
- It's especially easy when poking with strange network packets
- (so it's possible to perform remote DoS attack). Unfortunately, DoS
- if probably all you can do - enjoy SEGV in klogd daemon, or (better?),
- by overwriting fd to /proc/kmsg lyingo on the stack, increase LA and
- generate enormous amount of error messages like 'Cannot read /proc
- filesystem', apparently from kernel.
-
- b) ...or, in kernel (2.1.xxx is more interesting), locate any printk with
- %s in format string, where substituted string depends in some way on
- luser (process/filename?). Then, you should be able to parse arbitrary
- shellcode into buffer, obtaining root privledges.
-
- Solution:
-
- In klog.c, at the beginning, there are two '#define's. First one is
- responsible for main buffer size - don't change it, 4096 should be ok. The
- next one is line buffer size - hmm, replace 1024 with 4096, for example...
- Or, better, implement some range checking ;>
-
- Quick vunerability test:
-
- -- gcc -c -O3 test.c; insmod test; rmmod test --
- #define MODULE
- #define __KERNEL__
-
- #include <linux/module.h>
- #include <linux/kernel.h>
- #include <linux/types.h>
- #include <linux/string.h>
- #include <linux/malloc.h>
- #include <asm/unistd.h>
- #include <linux/version.h>
- #include <asm/string.h>
-
- int init_module(void) {
- printk("INSERT_ABOUT_2000_BYTES_OF_JUNK_HERE\n"); return 0;
- }
-
- void cleanup_module(void) {}
- --
-
- Modify this source by increasing amount of junk after printk, compile,
- insmod and watch out what happened to klogd.
-
- _______________________________________________________________________
- Michal Zalewski [lcamtuf@ids.pl] [ENSI / marchew] [dione.ids.pl SYSADM]
- [http://linux.lepszy.od.kobiety.pl/~lcamtuf/] <=--=> bash$ :(){ :|:&};:
- [voice phone: +48 (0) 22 813 25 86] ? [pager (MetroBip): 0 642 222 813]
- Iterowac jest rzecza ludzka, wykonywac rekursywnie - boska [P. Deutsch]
-